package com.sheng.project.study.cglib;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.LazyLoader;

/**
 * @author liusheng
 * @date 2023/06/29
 */
public class LazyLoaderTest1 {

    public static void main(String[] args) {
        // LazyLoader 是 cglib 用于实现懒加载的 callback。当被增强 bean 的方法初次被调用时，会触发回调，
        // 之后每次再进行方法调用都是对 LazyLoader 第一次返回的 bean 调用，hibernate 延迟加载有用到过这个。
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserModel.class);
        // 创建一个 LazyLoader 对象
        LazyLoader lazyLoader = new LazyLoader() {
            @Override
            public Object loadObject() throws Exception {
                System.out.println("调用 LazyLoader.loadObject() 方法");
                return new UserModel("黄金鹏");
            }
        };
        enhancer.setCallback(lazyLoader);
        Object proxy = enhancer.create();
        UserModel userModel = (UserModel) proxy;
        // 当第 1 次调用 say 方法的时候，会被 cglib 拦截，进入 lazyLoader 的 loadObject 内部，
        // 将这个方法的返回值作为 say 方法的调用者，loadObject 中返回了一个 黄金鹏 的 UserModel，
        // cglib 内部会将 loadObject 方法的返回值和 say 方法关联起来，然后缓存起来，
        // 而第 2 次调用 say 方法的时候，通过方法名去缓存中找，会直接拿到第 1 次返回的 UserModel，
        // 所以第 2 次不会进入到 loadObject 方法中了。
        System.out.println("第 1 次调用 say 方法");
        userModel.say();
        System.out.println("第 2 次调用 say 方法");
        userModel.say();
    }

    public static class UserModel {
        private String name;

        public UserModel() {
        }

        public UserModel(String name) {
            this.name = name;
        }

        public void say() {
            System.out.println("你好：" + name);
        }
    }
}
